package com.frejoys.notify.controller;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.frejoys.common.aop.Authority;
import com.frejoys.common.aop.Authorization;
import com.frejoys.common.config.ValueConfig;
import com.frejoys.common.constant.CommonConstant;
import com.frejoys.common.dto.common.notify.OssCallbackDto;
import com.frejoys.common.enums.EResourceStatus;
import com.frejoys.common.error.HttpStatus;
import com.frejoys.common.exception.GeneralException;
import com.frejoys.common.response.Result;
import com.frejoys.common.util.JwtUtil;
import com.frejoys.service.ResourceLibraryService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.nio.charset.StandardCharsets;

@Tag(name = "oss上传回调", description = "oss上传回调")
@RestController
@RequiredArgsConstructor
@RequestMapping(CommonConstant.routePrefixNotify)
@Authorization(Authority.Public)
@Slf4j
public class OssFileController {

    private final RedissonClient redissonClient;

    private final ResourceLibraryService resourceLibraryService;

    private final ValueConfig valueConfig;

    @Operation(summary = "服务端签名直传并设置上传回调测试")
    @PostMapping("/oss/callback/test")
    public String ossCallbackTest(HttpServletRequest request) {
        return JSONUtil.toJsonStr(Result.success());
    }

    @Operation(summary = "服务端签名直传并设置上传回调")
    @PostMapping("/oss/callback")
    public String ossCallback(HttpServletRequest request) {

        // String res = "{\"Status\":\"fail11\"}";
        String res = JSONUtil.toJsonStr(Result.fail(HttpStatus.uploadCallbackFileFail.getCode(), HttpStatus.uploadCallbackFileFail.getMsg(), null));

        try {

            String body = IoUtil.read(request.getInputStream(), StandardCharsets.UTF_8);
            OssCallbackDto dto = JSONUtil.toBean(StrUtil.replace(body, "\"\"", "\""), OssCallbackDto.class);

            RLock lock = redissonClient.getLock(dto.getFilename());

            try {
                // 上锁
                lock.lock();

                // 验证
                String fname = JwtUtil.verify(dto.getToken(), valueConfig.getUploadJwtCallbackSecret(), CommonConstant.fname);
                if (!fname.equals(dto.getFilename())) {
                    throw new GeneralException(HttpStatus.uploadCallbackFnameError);
                }
                if (StrUtil.isEmpty(fname)) {
                    throw new GeneralException(HttpStatus.uploadCallbackTokenNoExist);
                }

                // 更新图片为已经上传
                resourceLibraryService.upStatus(fname, EResourceStatus.wait.getValue(), EResourceStatus.uploaded.getValue());
                // System.out.println("图片上传成功了啊啊啊啊啊");
                // log.error("这是图上传成功");

            } catch (Exception e) {
                e.printStackTrace();
                return res;
            } finally {
                if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                    lock.unlock();
                }
            }

            // return "{\"Status\":\"ok\"}";
            return JSONUtil.toJsonStr(Result.success());
        } catch (Exception e) {
            e.printStackTrace();
            return res;
        }
    }

}
